package com.excelOperation.controller;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.excelOperation.service.ExcelOperationService;
import com.excelOperation.vo.ExcelVo;
import com.util.ExcelUitl;

@RequestMapping("excelOperation")
@Controller
public class ExcelOperationController {
	
	@Autowired
	private ExcelOperationService excelOperationServiceImp;

	
	//得到所有的人员list
    private Map<String, String> userInfo =new HashMap<String, String>();
	
   	//人员周数据list
   	private List<String> uassList = new ArrayList<String>();
    
	//主管，分总，总监Map
	private Map<String, String> userName =new HashMap<String, String>();
	
	@RequestMapping("downloadFile")
	@ResponseBody
	public String downloadFile(HttpServletRequest request,HttpServletResponse response){
		List<ExcelVo> excelList =excelOperationServiceImp.selUserAssociationfo();
		//字段名和字段值对应
	    LinkedHashMap<String, String> fieldMap =getFieldMap();
	    //文件名
	     String fileName="人员对应表信息";		     
	     try {
				ExcelUitl.listToExcel(excelList,fieldMap,fileName, response,request);			
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
		return "ss";
	}
	   	
	//enctype="multipart/form-data"  MultipartFilter @RequestParam("file") ss filter,@RequestParam("file") MultipartFilter filter,
	@RequestMapping("uploadFile")
	@ResponseBody
	public String uploadFile(HttpServletRequest request,HttpServletResponse response) throws IOException, BiffException{	   
		// 强转成SpringMVC的文件上传类	 		  
        MultipartHttpServletRequest mr = (MultipartHttpServletRequest) request;         
        // 获取上传的文件  
        MultipartFile multiFile = (MultipartFile) mr.getFile("file"); 
        // 获得文件全名  
        String fname = multiFile.getOriginalFilename();
        //获取文件的流
        InputStream in=multiFile.getInputStream();
        // 根据Excel数据源创建WorkBook
	    Workbook wb = Workbook.getWorkbook(in);	   
	    // 获取工作表
		Sheet sheet = wb.getSheet(0);
		// 获取工作表的名称 
        String sheetName=sheet.getName();
        // 获取Sheet表中所包含的 总 列 数
        int sheetColumns=sheet.getColumns();
        // 获取Sheet表中所包含的 总 行 数
        int sheetRows=sheet.getRows();
       
        // 获取某一 列 的所有单元格，返回的是单元格对象数组       
        Cell [] sheetColumn=sheet.getColumn(2);
        // 获取某一 行 的所有单元格，返回的是单元格对象数组
        Cell[] sheetRow = sheet.getRow(2);
        for (int i = 0; i < 6; i++) {
        	                         //得到 单元格里的值
			System.out.println("列="+sheetColumn[i].getContents().trim());
			System.out.println("行="+sheetRow[i].getContents().trim());
		}       
        //获取指定单元格的对象引用，需要注意的是它的两个参数，第一个是列数，第二个是行数，
        Cell sheetCell = sheet.getCell(0, 0);       
        System.out.println("单元格"+sheetCell.getContents().trim());       
        String sheet08 = sheet.getCell(8, 0).getContents().trim();
        String string08=sheet08.substring(sheet08.indexOf("<")+1, sheet08.indexOf(">")).split("-")[1];       
        String [] aa10= sheet08.split("\\."); 
     
        long t1, t2,t3, t4;
    	t1 = System.currentTimeMillis();
      //判断四个周时间是否正确,列名,顺序是否正确(正确的数组是16位)
      List<String> dateArray=judgeWeekCondition(sheet);    
      if (dateArray.size()!=16) {
    	 return "错误信息:"+dateArray.get(0).toString();
	  } 
      
      //得到所有的人员map      
      this.userInfo= excelOperationServiceImp.selUserInfo();
      this.userInfo.put("","");
           
     //得到当前月人员对应表的信息
     Integer year=Integer.parseInt(sheet.getCell(1, 1).getContents().trim());
     Integer month=Integer.parseInt(dateArray.get(0));
     if (year !=null && month !=null) {
		 //人员周数据list
	      this.uassList=excelOperationServiceImp.selAssociationInfo(year, month);
	  } else {
		  return "数据错误";
	  }
	 
	  	                    
      //得到错误的行数集合
      Map<Integer, String> errorColumns=getErrorColumns(sheet);
            
      //正确数据list
      List<ExcelVo> yesExcelVos=new ArrayList<ExcelVo>();
      //错误数据list
      List<ExcelVo> noExcelVos=new ArrayList<ExcelVo>();
      
      //向list中赋值
      for (int k = 1; k <5; k++) {					
	        //循环行数
	        for (int i = 1; i < sheet.getRows(); i++) {
	        	//判断数据加入哪个集合中
	        	if (!errorColumns.containsKey(i)) {
	        		yesExcelVos.add(addListValue(sheet, i, k, dateArray,""));
				 }else {
					 if (k==1) {
						 noExcelVos.add(addListValue(sheet, i, k, dateArray,errorColumns.get(i)));
					 }					
				 }																					
		   }	        	       	 
       }  
      //判断是否返回数据
		if (noExcelVos.size()==0) {
			excelOperationServiceImp.insertExcelInfo(yesExcelVos);
			return "上传成功";
		} else { 						
			//字段名和字段值对应
		     LinkedHashMap<String, String> fieldMap=getFieldMap();
		     fieldMap.put("oneWeek",sheet.getCell(8, 0).getContents().trim());
		     fieldMap.put("twoWeek",sheet.getCell(9, 0).getContents().trim());
		     fieldMap.put("threeWeek",sheet.getCell(10, 0).getContents().trim());
		     fieldMap.put("fourWeek",sheet.getCell(11, 0).getContents().trim());
		     fieldMap.put("errorInfo","错误信息(上传时请删掉)");	  
		     //文件名
		     String fileName="错误信息";	    
			try {
				if (yesExcelVos.size()>0) {					 
					t3 = System.currentTimeMillis(); 
					excelOperationServiceImp.insertExcelInfo(yesExcelVos);
					t4 = System.currentTimeMillis();
					System.out.println("插插插插插插插插插插插插插插插插插插插插插插:" + (t4 - t3) + "(ms)");
				}				
				ExcelUitl.listToExcel(noExcelVos,fieldMap,fileName, response,request);			
			} catch (Exception e) {
				e.printStackTrace();
			} 	
			t2 = System.currentTimeMillis();
			System.out.println("试试事实上事实上事实上事实上事实上事实上用时:" + (t2 - t1) + "(ms)");
			
			return "sss";
			
	   }
	 		
}


	/**
	 * 数据赋值(数据sheet， 行号i，第几周k，日期集合，错误信息)
	 * @param sheet
	 * @param i
	 * @param k
	 * @param dateArray
	 * @param errorInfo
	 * @return
	 */
	public ExcelVo addListValue(Sheet sheet,int i, int k,List<String> dateArray,String errorInfo){
		ExcelVo excelVo=new ExcelVo(); 
    	excelVo.setStaffId(sheet.getCell(0, i).getContents().trim()); //员工号
    	excelVo.setYearId(sheet.getCell(1, i).getContents().trim()); //年
    	excelVo.setMonthId(dateArray.get(0));//月
    	excelVo.setUserProvince(sheet.getCell(2, i).getContents().trim());//省份
    	excelVo.setUserResponsibleId(getCodeValue(sheet.getCell(3, i).getContents().trim()));//主管code
    	excelVo.setUserResponsibleName(sheet.getCell(3, i).getContents().trim());//主管
    	excelVo.setUserManagerId(getCodeValue(sheet.getCell(4, i).getContents().trim())); //分总code
    	excelVo.setUserManagerName(sheet.getCell(4, i).getContents().trim()); //分总
    	excelVo.setUserTotalId(getCodeValue(sheet.getCell(5, i).getContents().trim())); //总监code
    	excelVo.setUserTotalName(sheet.getCell(5, i).getContents().trim()); //总监
    	excelVo.setUserRegion(sheet.getCell(6, i).getContents().trim()); //区域
    	excelVo.setUserScName(sheet.getCell(7, i).getContents().trim()); //姓名
    	if (k==1) {
    		excelVo.setWeekId("1");//周
    		excelVo.setStartWeekDate(sheet.getCell(1, i).getContents().trim()+"-"+dateArray.get(0)+"-"+dateArray.get(1));//开始时间
    		excelVo.setEndWeekDate(sheet.getCell(1, i).getContents().trim()+"-"+dateArray.get(2)+"-"+dateArray.get(3));//结束时间			 		
		    excelVo.setUserWeeklyTask(sheet.getCell(8, i).getContents().trim());//全部任务量
    	} else if(k==2) {
			excelVo.setWeekId("2");
    		excelVo.setStartWeekDate(sheet.getCell(1, i).getContents().trim()+"-"+dateArray.get(4)+"-"+dateArray.get(5));
    		excelVo.setEndWeekDate(sheet.getCell(1, i).getContents().trim()+"-"+dateArray.get(6)+"-"+dateArray.get(7));
    		excelVo.setUserWeeklyTask(sheet.getCell(9, i).getContents().trim());
    	} else if(k==3) {
			excelVo.setWeekId("3");
    		excelVo.setStartWeekDate(sheet.getCell(1, i).getContents().trim()+"-"+dateArray.get(8)+"-"+dateArray.get(9));
    		excelVo.setEndWeekDate(sheet.getCell(1, i).getContents().trim()+"-"+dateArray.get(10)+"-"+dateArray.get(11));
    		excelVo.setUserWeeklyTask(sheet.getCell(10, i).getContents().trim());
    	}else if(k==4) {
			excelVo.setWeekId("4");
    		excelVo.setStartWeekDate(sheet.getCell(1, i).getContents().trim()+"-"+dateArray.get(12)+"-"+dateArray.get(13));
    		excelVo.setEndWeekDate(sheet.getCell(1, i).getContents().trim()+"-"+dateArray.get(14)+"-"+dateArray.get(15));
    		excelVo.setUserWeeklyTask(sheet.getCell(11, i).getContents().trim());//全部任务量
    	} 
    	excelVo.setUserPhoneTask(sheet.getCell(12, i).getContents().trim()); //手机任务量
    	excelVo.setUserSjnpTask(sheet.getCell(13, i).getContents().trim());//手机内配任务量
    	excelVo.setUserRemarks(sheet.getCell(14, i).getContents().trim());//备注
    	//错误信息添加
    	excelVo.setOneWeek(sheet.getCell(8, i).getContents().trim());
    	excelVo.setTwoWeek(sheet.getCell(9, i).getContents().trim());
    	excelVo.setThreeWeek(sheet.getCell(10, i).getContents().trim());
    	excelVo.setFourWeek(sheet.getCell(11, i).getContents().trim());
    	excelVo.setErrorInfo(errorInfo);
    	return excelVo;
	}
	
	
	/**
	 * 得到Excel字段和实体类字段的对应Map
	 * @return
	 */
	public LinkedHashMap<String, String> getFieldMap(){
		//字段名和字段值对应
	     LinkedHashMap<String, String> fieldMap =new LinkedHashMap<String, String>();
	     fieldMap.put("staffId", "员工号");
	     fieldMap.put("yearId", "年");
	     fieldMap.put("userProvince","省份");
	     fieldMap.put("userResponsibleName","主管");
	     fieldMap.put("userManagerName","分总");
	     fieldMap.put("userTotalName","总监");
	     fieldMap.put("userRegion","区域");
	     fieldMap.put("userScName","姓名");
	     fieldMap.put("oneWeek","第一周任务量<?.?-?.?>");
	     fieldMap.put("twoWeek","第二周任务量<?.?-?.?>");
	     fieldMap.put("threeWeek","第三周任务量<?.?-?.?>");
	     fieldMap.put("fourWeek","第四周任务量<?.?-?.?>");
	     fieldMap.put("userPhoneTask","任务量(手机)");
	     fieldMap.put("userSjnpTask","任务量(内配)");
	     fieldMap.put("userRemarks","备注");
	       	     
		return fieldMap;
	}
	
	/**
	 * 判断上传的四个周是否正确,列名,顺序是否正确
	 * @param sheet
	 * @return
	 */
   public List<String> judgeWeekCondition(Sheet sheet){
		
		//错误变量
		boolean error=true;
		//得到上传的月
        String maxDate="";
        //插入数组下标
        int x=0;
        //最后存放的数组
       List<String> dateArray =new ArrayList<String>();
        //得到标准列
        List<String> Column=new ArrayList<String>();
        LinkedHashMap<String, String> fieldMap=getFieldMap();
        for (String string : fieldMap.keySet()) {
        	String ssString=fieldMap.get(string);
        	Column.add(ssString);
		}
        //判断日期是否正确(循环标准列的下标)
        for (int i = 0; i < Column.size(); i++) {
        	if (i>7 && i<12) {
	        	//得到  第一周任务量<10.1-10.9>
	        	String cellValue=sheet.getCell(i, 0).getContents().trim();
	        	String[] ss1 =cellValue.substring(cellValue.indexOf("<")+1,cellValue.indexOf(">")).split("-"); 	    	        	         
	        	//判断是否第一次读取;
	        	if (x==0) {
	        		//得到上传的月 10
	        		maxDate=ss1[0].split("\\.")[0];
				} 
	        	//拆分为数字(10 1 10 9)
	        	for (int j = 0; j <ss1.length; j++) {
	        		 //得到10 1
	                 String [] ss2= ss1[j].split("\\.");
	                 for (int k = 0; k < ss2.length; k++) {
	                	 //判断是否跨月
	                	 if (!ss2[0].equals(maxDate)) {
	                		 dateArray.add("跨'"+ss2[0]+"'月了");
	                		 error=false;
	                		 break;
						 }                	                	 
	                	 dateArray.add(ss2[k]);
					}      		
				}	
			}else {
				//得到Excel表格的列
				String cellValue=sheet.getCell(i, 0).getContents().trim();	
				//比较Excel表格的列和标准列是否相同
				if (!cellValue.equals(Column.get(i))) {
					 dateArray.add("此列'"+cellValue+"'不对.请对照模板,输入-'"+Column.get(i)+"'");	
					 error=false;
					 break;					
				 }
			}       	       	       	       	       	
        }
        
        if (error) {
        	//判断日期是否是1号开始
            if (!"1".equals(dateArray.get(1))) {
    			 dateArray.set(0,dateArray.get(0)+"月份开始日期不对，请用1号开始");
    			 //判断条件，让数组不等16
    			 dateArray.add("月份开始日期不对，请用1号开始");
    			 return dateArray;
    		} 
         
            //设置为报表的时间
            Integer year=0;
            try {
            	year=Integer.parseInt(sheet.getCell(1,1).getContents().trim());
			} catch (Exception e) {
				dateArray.set(0,"请设置正确的年份");
				//判断条件，让数组不等16
   			    dateArray.add("请设置正确的年份");
    			return dateArray;
			}           
            Integer month =Integer.parseInt(dateArray.get(0));       
            Calendar ca = Calendar.getInstance();
            ca.set(year,month,01);//设置日期
            ca.add(Calendar.MONTH, -1); //要减一
            String ss=ca.getActualMaximum(Calendar.DAY_OF_MONTH)+"";//得到当月的最后一天
            //判断结束日期是否正确
            if (!ss.equals(dateArray.get(15))) {
    			 dateArray.set(0,dateArray.get(0)+"月份结束日期不对，结束日期为"+ss+"号");
    			 //判断条件，让数组不等16
    			 dateArray.add("月份开始日期不对");	
    			 return dateArray;
    		 }
             
            //判断第一周时间和第二周时间连不连续
            Integer ss3=Integer.parseInt(dateArray.get(3));
            Integer ss5=Integer.parseInt(dateArray.get(5))-1;      
             if (ss3!=ss5) {
            	 dateArray.set(0,"第一周时间和第二周时间不连续");
            	//判断条件，让数组不等16
            	 dateArray.add("第一周时间和第二周时间不连续");
            	 return dateArray;
    		 }
             
             //判断第二周时间和第三周时间连不连续
             Integer ss7=Integer.parseInt(dateArray.get(7));
             Integer ss9=Integer.parseInt(dateArray.get(9))-1;  
              if (ss7!=ss9) {
             	 dateArray.set(0,"第二周时间和第三周时间不连续");
             	//判断条件，让数组不等16
             	 dateArray.add("第二周时间和第三周时间不连续");
             	return dateArray;
     		  }
              
              //判断第三周时间和第四周时间连不连续
              Integer ss11=Integer.parseInt(dateArray.get(11));
              Integer ss13=Integer.parseInt(dateArray.get(13))-1;  
               if (ss11!=ss13) {
              	 dateArray.set(0,"第三周时间和第四周时间不连续");
              	//判断条件，让数组不等16
              	 dateArray.add("第三周时间和第四周时间不连续");
              	 return dateArray;
      		 }
        }
        return dateArray;
        
  }
    
	/**
	 * 根据名字得到code值
	 * @param name
	 * @return
	 */		
    public String getCodeValue(String name){
    	String Code="";   	
    	if (!name.isEmpty()) {
    		//得到主管集合的数据 
    		Code=this.userName.get(name);
    		//判断是否拿到
			if (Code !=null) {
				return Code;
			}else {
				for (String value : this.userInfo.keySet()) {
					if (this.userInfo.get(value).equals(name)) {
						Code=value;
						//把得到的值放入主管集合里
						userName.put(name, value);
						break;
					}
				}				
				return Code;
			}  		
		}else {
			return Code;
		}	        
    }		
     
    /**
	 *得到错误的列的序号 
	 */
    public Map<Integer, String> getErrorColumns(Sheet sheet){
    	
    	//已判断的人员集合
    	List<String> judgeInfo=new ArrayList<String>();
    	
    	Map<Integer, String> errorColumns=new HashMap<Integer,String>();
        //循环行数
        for (int i = 1; i < sheet.getRows(); i++) {
        	boolean condition= false;
          //错误信息
           StringBuffer errorInfo=new StringBuffer();               
        	String celld00=sheet.getCell(0, i).getContents().trim();	
        	String celld03=sheet.getCell(3, i).getContents().trim();
        	String celld04=sheet.getCell(4, i).getContents().trim();
        	String celld05=sheet.getCell(5, i).getContents().trim();
        	String celld07=sheet.getCell(7, i).getContents().trim();
        	//判断是否有此人
        	if (this.userInfo.containsKey(celld00)) {
        		//判断code值和名字是否相同
        		if (this.userInfo.get(celld00).equals(celld07)) {
        			//判断周数据中是否有此人
            		if (!this.uassList.contains(celld00)) {
            			//无此人就加入已判断的人员集合中
    	        		judgeInfo.add(celld00);
    					//从人员周数据集合中删除此人
            			this.uassList.remove(celld00);    			
    				}else {					
    					errorInfo.append("有此人的周数据:"+celld00+";");
                		condition=true;
    				}        			
				}else {
					errorInfo.append("此人的code和名字不对应:"+celld00+";");
            		condition=true;
				}
        		       		
			}else {
				//判断是否人员重复
    			if (judgeInfo.contains(celld00)) {
    				errorInfo.append("此人的code重复:"+celld00+";");           			
            		condition=true;
				}else {
					errorInfo.append("无此人:"+celld00+";"); 
	        		condition=true;										
				} 				
			}	        	
        	//判断是否有此主管 
    		if (!this.userInfo.containsValue(celld03)) {
    			errorInfo.append("无此主管:"+celld03+";");  
    			condition=true;
			} 	        	
        	//判断是否有此分总    		
			if (!this.userInfo.containsValue(celld04)) {
				errorInfo.append("无此分总:"+celld04+";");	
				condition=true;
			}	        	
        	//判断是否有此总监				
			if (!this.userInfo.containsValue(celld05)) {
				errorInfo.append("无此总监:"+celld05+";");
				condition=true;
			}
			
			//错误行进入
			if (condition) {
				errorColumns.put(i, errorInfo.toString());   	
			}
       }
     return errorColumns;    
   }
}
